package com.tanxi521.tnweb.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.tanxi521.tnweb.mapper.*;
import com.tanxi521.tnweb.model.*;
import com.tanxi521.tnweb.service.PlayerAccountService;
import com.tanxi521.tnweb.utils.DownLoadUtils;
import com.tanxi521.tnweb.utils.HttpClientUtils;
import com.tanxi521.tnweb.utils.Result;
import com.tanxi521.tnweb.utils.SHA256Util;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.configuration.file.YamlConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yaml.snakeyaml.Yaml;

import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class PlayerAccountServiceImpl implements PlayerAccountService {

    @Autowired
    PlayerAccountMapper playerAccountMapper;

    @Autowired
    WebUserMapper webUserMapper;

    @Autowired
    VipPlayersMapper vipPlayersMapper;

    @Autowired
    PlayerSkinMapper playerSkinMapper;

    @Autowired
    PlayerStatusMapper playerStatusMapper;

    @Autowired
    PlayerLevelMapper playerLevelMapper;

    @Autowired
    PlayerPointsMapper playerPointsMapper;

    @Autowired
    PlayerMoneyMapper playerMoneyMapper;

    @Autowired
    MailBoxPlayerMapper mailBoxPlayerMapper;

    @Autowired
    MarriagePlayerMapper marriagePlayerMapper;

    @Autowired
    GayPlayersMapper gayPlayersMapper;

    @Autowired
    PlayerBoundRewardsMapper playerBoundRewardsMapper;

    @Autowired
    MailBoxFileMapper mailBoxFileMapper;

    @Override
    public int getPlayerCount() {
        return playerAccountMapper.selectAllPlayerCount();
    }

    @Override
    public int getOnlineNums() {
        return playerAccountMapper.selectOnlineNums();
    }

    @Override
    public PlayerAccount queryPlayerByPlayerId(int id) {
        return playerAccountMapper.selectByPrimaryKey(id);
    }

    @Override
    public PlayerAccount queryPlayerByPlayerName(String mcId, String mcPassword, HttpSession session) throws Exception {
        List<PlayerAccount> players = playerAccountMapper.selectPlayerByPlayerName(mcId);
        if (players.size() > 0) {
            PlayerAccount playerAccount = players.get(0);
            if (playerAccount.getHassession() == 1) {
                short hasSession = 0;
                playerAccount.setHassession(hasSession);
                return playerAccount;
            }
            String password = playerAccount.getPassword();
            String salt = password.substring(5, 21);
            String inPass = "$SHA$" + salt + "$" + SHA256Util.getSHA256(mcPassword + salt);
            if (StringUtils.equals(password, inPass)) {
                WebUser webUser = (WebUser) session.getAttribute("webUser");
                webUser.setIsBound(1);
                webUser.setMcId(playerAccount.getId());
                webUserMapper.updateByPrimaryKey(webUser);
                short hasSession = 1;
                playerAccount.setHassession(hasSession);
                playerAccountMapper.updateByPrimaryKey(playerAccount);
                VipPlayers vipPlayers = vipPlayersMapper.selectByPlayerRealname(mcId);
                PlayerBoundRewards playerBoundRewards = new PlayerBoundRewards();
                playerBoundRewards.setPlayerName(mcId);
                playerBoundRewards.setIsrewards(0);
                playerBoundRewardsMapper.insert(playerBoundRewards);
                session.setAttribute("playerAccount", playerAccount);
                session.setAttribute("vipPlayers", vipPlayers);
                String getPlayerUUID = "https://api.mojang.com/users/profiles/minecraft/" + mcId;
                String playerUUIDResult = null;
                try {
                    playerUUIDResult = HttpClientUtils.doGet(getPlayerUUID);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                PlayerSkin playerSkin = new PlayerSkin();
                if (!StringUtils.equals("", playerUUIDResult)) {
                    JSONObject jsonObject = JSONObject.parseObject(playerUUIDResult);
                    String uuid = jsonObject.getString("id");
                    String getPlayerSkinInfo = "https://sessionserver.mojang.com/session/minecraft/profile/" + uuid;
                    String playerSkinResult = null;
                    try {
                        playerSkinResult = HttpClientUtils.doGet(getPlayerSkinInfo);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    JSONObject jsonObject1 = JSONObject.parseObject(playerSkinResult);
                    String properties = jsonObject1.getString("properties");
                    String substring = properties.substring(properties.indexOf("[") + 1, properties.indexOf("]"));
                    JSONObject skinValue = JSONObject.parseObject(substring);
                    String value = skinValue.getString("value");
                    byte[] decode = Base64.getDecoder().decode(value);
                    String playerSkinValue = new String(decode);
                    JSONObject jsonObject2 = JSONObject.parseObject(playerSkinValue);
                    String string = jsonObject2.getString("textures");
                    JSONObject skinUrlBefore = JSONObject.parseObject(string);
                    String skin = skinUrlBefore.getString("SKIN");
                    JSONObject skinUrl = JSONObject.parseObject(skin);
                    String url = skinUrl.getString("url");
                    DownLoadUtils.download(url, mcId, "D:\\MC服务器\\web\\user\\user_player_skin");
                    playerSkin.setPlayerName(mcId);
                    playerSkin.setPlayerSkinPath("/tnweb/image/user_player_skin/" + mcId + ".png");
                    playerSkinMapper.insert(playerSkin);
                } else {
                    playerSkin.setPlayerName(mcId);
                    playerSkin.setPlayerSkinPath("/tnweb/image/user_player_skin/default.png");
                    playerSkinMapper.insert(playerSkin);
                }
                return playerAccount;
            } else {
                playerAccount.setPassword("账号或密码错误");
                return playerAccount;
            }
        }
        return null;
    }

    @Override
    public PlayerPageInfo getPlayerInfo(String userId) {
        PlayerPageInfo playerPageInfo = new PlayerPageInfo();
        List<PlayerAccount> playerAccounts = playerAccountMapper.selectPlayerByPlayerName(userId);
        if (playerAccounts.size() == 0) {
            playerPageInfo.setOnlineStatus("信息获取失败");
            playerPageInfo.setPlayerRegTime("信息获取失败");
            playerPageInfo.setPlayerLastLoginTime("信息获取失败");
        } else {
            PlayerAccount playerAccount = playerAccounts.get(0);
            if (playerAccount.getIslogged() == 1) {
                playerPageInfo.setOnlineStatus("游戏在线");
            } else {
                playerPageInfo.setOnlineStatus("游戏离线");
            }
            Date regDate = new Date(playerAccount.getRegdate());
            Date lastLoginDate = new Date(playerAccount.getLastlogin());
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            playerPageInfo.setPlayerRegTime(format.format(regDate));
            playerPageInfo.setPlayerLastLoginTime(format.format(lastLoginDate));
        }

        List<PlayerStatus> playerStatuses = playerStatusMapper.selectByPlayerName(userId);
        if (playerStatuses.size() == 0) {
            playerPageInfo.setPlayerHealth("无");
            playerPageInfo.setPlayerHunger("无");
        } else {
            PlayerStatus playerStatus = playerStatuses.get(0);
            playerPageInfo.setPlayerHealth(playerStatus.getHealth().toString());
            playerPageInfo.setPlayerHunger(playerStatus.getFood().toString());
            List<PlayerLevelWithBLOBs> playerLevels = playerLevelMapper.selectByPlayerName(userId);
            PlayerLevelWithBLOBs playerLevel = playerLevels.get(0);
            if (!ObjectUtils.allNotNull(playerLevel)) {
                playerPageInfo.setPlayerLevel("无");
                playerPageInfo.setPlayerExp("无");
                playerPageInfo.setPlayerExpToNextLevel("无");
            }
            playerPageInfo.setPlayerLevel(playerLevel.getPlayerLevel());
            playerPageInfo.setPlayerExp(playerLevel.getPlayerExp().toString());
            playerPageInfo.setPlayerExpToNextLevel(playerLevel.getPlayerMaxExp().toString());
        }
        List<PlayerPoints> playerPoints = playerPointsMapper.selectByPlayerName(userId);
        if (playerPoints.size() == 0) {
            playerPageInfo.setPlayerPoints("无");
        } else {
            PlayerPoints playerPoint = playerPoints.get(0);
            playerPageInfo.setPlayerPoints(playerPoint.getPoints().toString());
        }
        List<PlayerMoney> playerMonies = playerMoneyMapper.selectByPlayerName(userId);
        if (playerMonies.size() == 0) {
            playerPageInfo.setPlayerEco("无");
        } else {
            PlayerMoney playerMoney = playerMonies.get(0);
            playerPageInfo.setPlayerEco(playerMoney.getBalance().toString());
        }
        List<VipPlayers> vipPlayers = vipPlayersMapper.selectByPlayerName(userId);
        if (vipPlayers.size() == 0) {
            playerPageInfo.setPlayerVIP("无");
            playerPageInfo.setPlayerVIPRest("-");
        } else {
            VipPlayers vipPlayer = vipPlayers.get(0);
            playerPageInfo.setPlayerVIP(vipPlayer.getVip());
            if (vipPlayer.getDuration() > -1) {
                long time = new Date().getTime();
                long l = vipPlayer.getDuration() + vipPlayer.getStart();
                long rest = l - time;
                if (rest > 0) {
                    playerPageInfo.setPlayerVIPRest(rest / 1000 / 60 / 60 / 24 + " 天");
                } else {
                    playerPageInfo.setPlayerVIPRest("已到期");
                }
            }
            playerPageInfo.setPlayerVIPRest("永久");
        }
        int sendMail = mailBoxPlayerMapper.selectSendCountByPlayerName(userId);
        playerPageInfo.setPlayerSendMail(sendMail + "");
        int receiveMail = mailBoxPlayerMapper.selectReceiveCountByPlayerName(userId);
        playerPageInfo.setPlayerReceivedMail(receiveMail + "");

        List<GayPlayers> gayPlayersList = gayPlayersMapper.selectPlayerByName(userId);
        GayPlayers gayPlayers = null;
        String uniqueUserId = "";
        if (gayPlayersList.size() > 0) {
            gayPlayers = gayPlayersList.get(0);
            uniqueUserId = gayPlayers.getUniqueUserId();
        }
        List<MarriagePlayer> marriagePlayers = marriagePlayerMapper.selectByPlayerName(uniqueUserId);
        if (marriagePlayers.size() == 0) {
            playerPageInfo.setIsMarry("未婚");
            playerPageInfo.setMarryLover("无");
        } else {
            MarriagePlayer marriagePlayer = marriagePlayers.get(0);
            playerPageInfo.setIsMarry("已婚");
            String player1 = marriagePlayer.getPlayer1();
            String player2 = marriagePlayer.getPlayer2();
            String userName1 = gayPlayersMapper.selectPlayerByUuid(player1);
            String userName2 = gayPlayersMapper.selectPlayerByUuid(player2);
            if (StringUtils.equals(userName1, userId)) {
                playerPageInfo.setMarryLover(userName2);
            } else {
                playerPageInfo.setMarryLover(userName1);
            }
        }
        List<PlayerSkin> playerSkins = playerSkinMapper.selectByPlayerName(userId);
        if (playerSkins.size() == 0) {
            playerPageInfo.setPlayerSkinPath("/tnweb/image/user_player_skin/default.png");
        } else {
            PlayerSkin playerSkin = playerSkins.get(0);
            playerPageInfo.setPlayerSkinPath(playerSkin.getPlayerSkinPath());
        }
        return playerPageInfo;
    }

    @Override
    @Transactional
    public Object deBoundMc(HttpSession session, String mcPassword) {
        WebUser user = (WebUser) session.getAttribute("webUser");
        PlayerAccount webPlayer = (PlayerAccount) session.getAttribute("playerAccount");
        PlayerAccount playerAccount = playerAccountMapper.selectByPrimaryKey(webPlayer.getId());
        WebUser webUser = webUserMapper.selectByPrimaryKey(user.getId());
        String password = playerAccount.getPassword();
        String salt = password.substring(5, 21);
        String inPass = "$SHA$" + salt + "$" + SHA256Util.getSHA256(mcPassword + salt);
        if (!StringUtils.equals(password, inPass)) return Result.error("密码错误，解绑失败");
        webUser.setMcId(0);
        webUser.setIsBound(0);
        short isBound = 0;
        playerAccount.setHassession(isBound);
        int playerUpdate = playerAccountMapper.updateByPrimaryKey(playerAccount);
        int webUpdate = webUserMapper.updateByPrimaryKey(webUser);
        int skinUpdate = playerSkinMapper.deleteByPlayerName(playerAccount.getRealname());
        if (playerUpdate == 1 && webUpdate == 1 && skinUpdate == 1) {
            return Result.success("取消绑定成功");
        }
        return Result.error("系统繁忙,请刷新页面重试");
    }

    @Override
    public MailBoxFile giveBoundRewards(String mcId) {
        int num = playerBoundRewardsMapper.updateByName(mcId);
        if (num == 0) {
            return null;
        }
        MailBoxFile mailBoxFile = new MailBoxFile();
        UUID uuid = UUID.randomUUID();
        String mailFile = uuid.toString().replace("-", "");
        Random random = new Random();
        Integer coins = random.nextInt(50000) + 50000;
        Integer points = random.nextInt(500) + 500;

//        YamlConfiguration cmd = new YamlConfiguration();
//        List<String> commandsList = new ArrayList<>();
//        commandsList.add("minecraft:give " + mcId + " advanced_solar_panels:machines 1 5");
//        commandsList.add("minecraft:give " + mcId + " appliedenergistics2:controller 5");
//        commandsList.add("minecraft:give " + mcId + " appliedenergistics2:storage_cell_64k 1");
//        cmd.set("commands", commandsList);
//        String commands = cmd.saveToString();
//        mailBoxFile.setCommands(commands);


        YamlConfiguration des = new YamlConfiguration();
        List<String> desList = new ArrayList<>();
        desList.add("量子太阳能一台");
        desList.add("AE一套");
        des.set("descriptions", desList);
        String descriptions = des.saveToString();
        String items = "is:\n" +
                "  is_1:\n" +
                "    ==: org.bukkit.inventory.ItemStack\n" +
                "    type: APPLIEDENERGISTICS2_PART\n" +
                "    damage: 380\n" +
                "  is_2:\n" +
                "    ==: org.bukkit.inventory.ItemStack\n" +
                "    type: APPLIEDENERGISTICS2_PART\n" +
                "    damage: 340\n" +
                "  is_3:\n" +
                "    ==: org.bukkit.inventory.ItemStack\n" +
                "    type: APPLIEDENERGISTICS2_PART\n" +
                "    damage: 480\n" +
                "  is_4:\n" +
                "    ==: org.bukkit.inventory.ItemStack\n" +
                "    type: APPLIEDENERGISTICS2_PART\n" +
                "    damage: 360\n" +
                "  is_5:\n" +
                "    ==: org.bukkit.inventory.ItemStack\n" +
                "    type: APPLIEDENERGISTICS2_PART\n" +
                "    damage: 16\n" +
                "    amount: 64\n" +
                "  is_6:\n" +
                "    ==: org.bukkit.inventory.ItemStack\n" +
                "    type: ADVANCED_SOLAR_PANELS_MACHINES\n" +
                "    damage: 5\n" +
                "  is_7:\n" +
                "    ==: org.bukkit.inventory.ItemStack\n" +
                "    type: APPLIEDENERGISTICS2_STORAGE_CELL_64K\n" +
                "  is_8:\n" +
                "    ==: org.bukkit.inventory.ItemStack\n" +
                "    type: APPLIEDENERGISTICS2_CONTROLLER\n" +
                "  is_9:\n" +
                "    ==: org.bukkit.inventory.ItemStack\n" +
                "    type: APPLIEDENERGISTICS2_DRIVE\n" +
                "  count: 9\n";
        mailBoxFile.setType("player");
        mailBoxFile.setFilename(mailFile);
        mailBoxFile.setDescriptions(descriptions);
        mailBoxFile.setCoin(coins + ".0");
        mailBoxFile.setPoint(points + "");
        mailBoxFile.setItems(items);
        mailBoxFileMapper.insert(mailBoxFile);

        MailBoxPlayer mailBoxPlayer = new MailBoxPlayer();
        mailBoxPlayer.setSender("北境官方");
        mailBoxPlayer.setRecipient(mcId);
        mailBoxPlayer.setTopic("感谢您绑定北境账号");
        mailBoxPlayer.setText("网站绑定奖励");
        mailBoxPlayer.setSendtime(new Date());
        mailBoxPlayer.setFilename(mailBoxFile.getFilename());

        mailBoxPlayerMapper.insert(mailBoxPlayer);
        return mailBoxFile;
    }
}
